if ( op->interface_version != XENPF_INTERFACE_VERSION )
return -EACCES;
- spin_lock(&xenpf_lock);
+ /* spin_trylock() avoids deadlock with stop_machine_run(). */
+ while ( !spin_trylock(&xenpf_lock) )
+ if ( hypercall_preempt_check() )
+ return hypercall_create_continuation(
+ __HYPERVISOR_platform_op, "h", u_xenpf_op);
switch ( op->cmd )
{
g_info = &op->u.pcpu_info;
- spin_lock(&cpu_add_remove_lock);
+ /* spin_trylock() avoids deadlock with stop_machine_run(). */
+ if ( !spin_trylock(&cpu_add_remove_lock) )
+ {
+ ret = -EBUSY;
+ break;
+ }
if ( (g_info->xen_cpuid >= NR_CPUS) ||
(g_info->xen_cpuid < 0) ||
{
int err = 0;
- spin_lock(&cpu_add_remove_lock);
+ /* spin_trylock() avoids deadlock with stop_machine_run(). */
+ if (!spin_trylock(&cpu_add_remove_lock)) {
+ err = -EBUSY;
+ goto out;
+ }
+
if (num_online_cpus() == 1) {
err = -EBUSY;
goto out;
{
int err = 0;
- spin_lock(&cpu_add_remove_lock);
+ /* spin_trylock() avoids deadlock with stop_machine_run(). */
+ if (!spin_trylock(&cpu_add_remove_lock))
+ return -EBUSY;
+
if (cpu_online(cpu)) {
printk("Bring up a online cpu. Bogus!\n");
err = -EBUSY;
if (cpu == 0)
continue;
error = cpu_down(cpu);
+ /* No need to check EBUSY here */
+ ASSERT(error != -EBUSY);
if (!error) {
cpu_set(cpu, frozen_cpus);
printk("CPU%d is down\n", cpu);
mtrr_aps_sync_begin();
for_each_cpu_mask(cpu, frozen_cpus) {
error = cpu_up(cpu);
+ /* No conflict will happen here */
+ ASSERT(error != -EBUSY);
if (!error) {
printk("CPU%d is up\n", cpu);
continue;
if ( physid_isset(apic_id, phys_cpu_present_map) )
return -EEXIST;
- spin_lock(&cpu_add_remove_lock);
+ /* spin_trylock() avoids deadlock with stop_machine_run(). */
+ if (!spin_trylock(&cpu_add_remove_lock))
+ return -EBUSY;
cpu = mp_register_lapic(apic_id, 1);
if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION )
return -EACCES;
- spin_lock(&sysctl_lock);
+ /* spin_trylock() avoids deadlock with stop_machine_run(). */
+ while ( !spin_trylock(&sysctl_lock) )
+ if ( hypercall_preempt_check() )
+ return hypercall_create_continuation(
+ __HYPERVISOR_sysctl, "h", u_sysctl);
switch ( op->cmd )
{